package com.hunan.api.catv.aop;

import com.hunan.api.catv.annotation.AdminAuthAnnotation;
import com.hunan.api.catv.common.CacheKey;
import com.hunan.api.catv.entity.Result;
import com.hunan.api.catv.entity.enums.ResultCode;
import com.hunan.api.catv.entity.vo.SystemUserVo;
import com.hunan.api.catv.utils.RedisUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.MessageFormat;

@Aspect
@Component
public class AdminAuthAspect {

    private final static Logger log = LoggerFactory.getLogger(AdminAuthAspect.class);

    @Autowired
    RedisUtils redisUtils;

    @Pointcut("@annotation(com.hunan.api.catv.annotation.AdminAuthAnnotation)")
    public void adminAuthPonitcut() {

    }

    @Around(value = "adminAuthPonitcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature sign = (MethodSignature) pjp.getSignature();
        Method method = sign.getMethod();
        AdminAuthAnnotation annotation = method.getAnnotation(AdminAuthAnnotation.class);
        boolean isAuth = annotation.isAuth();
        if (isAuth) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String token = request.getHeader("token");
            if (StringUtils.isEmpty(token)) {
                return new Result(ResultCode.unauthorized.getCode(), ResultCode.unauthorized.getMsg(), "");
            }
            String key = MessageFormat.format(CacheKey.adminToken, token);
            Object result = redisUtils.get(key);
            if (ObjectUtils.isEmpty(result)) {
                log.debug("[admin login token:{} isEmpty] ", key);
                return new Result(ResultCode.unauthorized.getCode(), ResultCode.unauthorized.getMsg(), "");
            }

            SystemUserVo systemUserVo = (SystemUserVo) result;
            log.info("[action operation package:{} method:{} userId:{} userIp:{} ]", sign.getDeclaringType().getName(), sign.getName(), systemUserVo.getSysUserId(), systemUserVo.getLoginIp());

            request.setAttribute("sysUser", result);
        }
        return pjp.proceed();
    }
}
